package Risk.IHM;

import Risk.Moteur.*;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.File;

import java.util.ArrayList;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * Fenetre de choix de carte
 * @author Sebastien Depoix
 */
public class ChoixCarteIHM extends JFrame implements ActionListener {
    private static ChoixCarteIHM	instance         = null;
    private static final long		serialVersionUID = 1L;
    private ArrayList<Integer>		alIndiceChoixCarte;
    private JButton			jbAnnulerChoix;
    private JButton			jbFermeture;
    private JButton			jbOK;
    private PlateauIhm			pihm;
    private Jeu				risk;
    private JButton[]			tabJBCartes;

    /**
     * Constructeur de la fenetre sans parametre
     */
    private ChoixCarteIHM() {
	super("Choix des cartes");

	this.initComponents(0);
	this.setResizable(true);
	this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
	this.setAlwaysOnTop(true);    // pour obliger la fermeture par le joueur
	this.pack();
        
        // position de la fenetre au millieur de l'ecran
	Dimension	ecran = Toolkit.getDefaultToolkit().getScreenSize();       
        Dimension frameSize = this.getSize();
        this.setLocation((ecran.width - frameSize.width)/2,(ecran.height - frameSize.height)/2);
        
	this.setVisible(false);
	this.pihm = null;
	this.risk = null;
    }

    /**
     * Actions lors du clic sur les boutons
     * @param e l'evenement
     */
    public void actionPerformed(ActionEvent e) {
	Object	o = (JButton) e.getSource();
        //verifie la combinaison et met a jour le nombre des cartes et la frame
	if (o.equals(jbOK)) {
	    if (this.verifierCombinaison()) {
		refreshCartes();
		refreshFrame();
	    }
	}
        //annule la selection des joueurs
	if (o.equals(jbAnnulerChoix)) {
	    annuler();
	}
        //fermeture fenetre
	if (o.equals(jbFermeture)) {
	    this.setVisible(false);
	}
        
	for (int i = 0; i < tabJBCartes.length; i++) {
	    if (o.equals(tabJBCartes[ i ])) {
		if ((alIndiceChoixCarte.size() < 3) && (pihm.getRisk().getPhase() == Jeu.RENFORT)) {
		    tabJBCartes[ i ].setEnabled(false);
		    alIndiceChoixCarte.add(i);
		    System.out.println("Carte : " + i + " => " + risk.getCartesJoueurCourant().get(i));

		    if (alIndiceChoixCarte.size() == 3) {
			jbOK.setEnabled(true);
		    }
		}
	    }
	}
    }

    private void annuler() {
	for (int i = 0; i < tabJBCartes.length; i++) {
	    tabJBCartes[ i ].setEnabled(true);
	}

	alIndiceChoixCarte.clear();
	jbOK.setEnabled(false);
    }

    /**
     * Initialisation des composants
     * @param taille
     */
    private void initComponents(int taille) {
	int	ligne, colonne;
	JPanel	jpBoutonCarte, jpAutreBouton;

	ligne   = taille / 3 + taille % 3;
	colonne = 3;
        
        //DEBUG
	// System.out.println("taille=" + taille + " ligne=" + ligne + " colonne=" + colonne);
	jpBoutonCarte = new JPanel(new GridLayout(ligne, colonne, 2, 5));
	tabJBCartes   = new JButton[ taille ];
        
        //panel dynamique des cartes
	for (int i = 0; i < tabJBCartes.length; i++) {

	    // Texte
	    tabJBCartes[ i ] = new JButton(risk.getCartesJoueurCourant().get(i).getPays().getNom());

	    // Image
	    File	fic = new File("Images" + File.separator + "Icons" + File.separator
				       + risk.getCartesJoueurCourant().get(i).getValeur() + ".png");
	    ImageIcon	ii = new ImageIcon(fic.getAbsolutePath());

	    ii.setImage(ii.getImage().getScaledInstance(ii.getIconHeight(), ii.getIconWidth(), Image.SCALE_DEFAULT));
	    tabJBCartes[ i ].setIcon(ii);

	    // Sebastien -> Si on veut que les icones soient au dessus du texte
	    tabJBCartes[ i ].setVerticalTextPosition(AbstractButton.BOTTOM);
	    tabJBCartes[ i ].setHorizontalTextPosition(AbstractButton.CENTER);

	    // les cartes des pays possedes sont affiches dans la couleur du joueur courant
	    if (risk.getCartesJoueurCourant().get(i).getPays().controlePays(risk.getJoueurCourant())) {
		tabJBCartes[ i ].setBackground(risk.getJoueurCourant().getCouleur());
	    }

	    tabJBCartes[ i ].addActionListener(this);
	    jpBoutonCarte.add(tabJBCartes[ i ]);
	}

	jpAutreBouton = new JPanel(new GridLayout(1, 2, 5, 5));

	// bouton valider
	jbOK = new JButton("Valider Choix");
	jbOK.addActionListener(this);
	jbOK.setEnabled(false);    //desactive en standard
	jpAutreBouton.add(jbOK);

	// bouton annuler
	jbAnnulerChoix = new JButton("Annuler Choix");
	jbAnnulerChoix.addActionListener(this);
	jpAutreBouton.add(jbAnnulerChoix);
	jbFermeture = new JButton("Fermer");
	jbFermeture.addActionListener(this);
	jpAutreBouton.add(jbFermeture);
	this.setLayout(new BorderLayout(10, 10));
	this.add(jpBoutonCarte, BorderLayout.CENTER);
	this.add(jpAutreBouton, BorderLayout.SOUTH);
	alIndiceChoixCarte = new ArrayList<Integer>();
    }
    /**
     * met a jour les cartes en main du joueur courant
     */
    public void refreshCartes() {

	// efface tout
	this.getContentPane().removeAll();

	// regenere tout
	this.initComponents(risk.getCartesJoueurCourant().size());
	this.pack();
    }
     /**
     * met a jour le panel du joueur courant
     */
    public void refreshFrame() {
	pihm.panelJoueurCourant();
    }

    /**
     * Verifiera si la combinaison de trois cartes est valables
     */
    private boolean verifierCombinaison() {
	int[]	tabCombi = new int[ 3 ];
	boolean	retour;
	int	i = 0;

	for (Integer indice : alIndiceChoixCarte) {
	    tabCombi[ i ] = indice;
	    i++;
	}

	System.out.println("Avant depense : " + risk.getJoueurCourant() + " a en reserve "
			   + risk.getReserveJoueurCourant() + " soldats");
	retour = risk.depenseCarteJoueurCourant(tabCombi);

	if (retour) {
	    System.out.println("Apres depense : " + risk.getJoueurCourant() + " a en reserve "
			       + risk.getReserveJoueurCourant() + " soldats");
	} else {
	    JOptionPane.showMessageDialog(this, "Votre combinaison de cartes est erronee.", "Erreur de combinaison",
					  JOptionPane.ERROR_MESSAGE);
	    annuler();
	}

	return retour;
    }

    /**
     * pour le patern singleton
     * @return instance - l'instance de la classe
     */
    public static ChoixCarteIHM getInstance() {
	if (instance == null) {
	    instance = new ChoixCarteIHM();
	}

	return instance;
    }
     /**
     * frame  a laquelle le choix des cartes bonus appartient
     * @param ihm - le plateau ihm
     */
    public void setFrame(PlateauIhm ihm) {
	this.pihm = ihm;
	setRisk(pihm.getRisk());
    }

    /**
     * pour fixer l'etat de la partie
     * @param risk - le jeu virtuel
     */
    private void setRisk(Jeu risk) {
	this.risk = risk;
    }
}
